﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

#ifndef zh
#define zh(a) QString::fromLocal8Bit(a)
#endif


//用于保存文件
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QSettings>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setWindowTitle(zh("8266小助手"));

    ui->recvData->setText(zh("串口小助手ver 1.1.0\n开发：泉源\n"));

    {
        {
            QStringList list = {"4800", "9600", "19200", "38400", "57600", "115200"};
            ui->baudRate->addItems(list);
        }
        {
            QStringList list = {"8 bit", "7 bit", "6 bit", "5 bit"};
            ui->checkBit->addItems(list);
        }
        {
            QStringList list = {"No Parity", "Odd Parity", "Even Parity", "Space Parity"};
            ui->dataBit->addItems(list);
        }
        {
            QStringList list = {"One Stop", "Two Stop"};
            ui->stopBit->addItems(list);
        }
        {
            QStringList list = {"None", "CR", "LF", "CR&LF"};
            ui->endString->addItems(list);
        }
    }

    {
        // 初始化文件
        //路径为程序路径下，文件不存在会自行创建
        QString iniFilePath = QCoreApplication::applicationDirPath() + "/config.ini";
        //新建QSettings类，路径+格式
        QSettings settings(iniFilePath,QSettings::IniFormat);
        //设置编码，使支持中文
        settings.setIniCodec("UTF-8");

        ui->baudRate->setCurrentIndex(settings.value("ADDRESS/baudRate").toString().toInt());
        ui->dataBit->setCurrentIndex(settings.value("ADDRESS/dataBit").toString().toInt());
        ui->stopBit->setCurrentIndex(settings.value("ADDRESS/stopBit").toString().toInt());
        ui->checkBit->setCurrentIndex(settings.value("ADDRESS/checkBit").toString().toInt());
        ui->endString->setCurrentIndex(settings.value("ADDRESS/endString").toString().toInt());
    }

    connect(ui->clearRecvCache, SIGNAL(clicked()), this, SLOT(clearData()));
    connect(ui->clearSentCache, SIGNAL(clicked()), this, SLOT(clearData()));

    connect(ui->saveRecvCache, SIGNAL(clicked()), this, SLOT(saveCache()));
    connect(ui->saveSentCache, SIGNAL(clicked()), this, SLOT(saveCache()));

    connect(ui->serialPortSearch, SIGNAL(clicked()), this, SLOT(serialPortButton()));
    connect(ui->serialToggle, SIGNAL(clicked()), this, SLOT(serialToggleButton()));
    connect(ui->Sent, SIGNAL(clicked()), this, SLOT(serialSentButton()));

    QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);
}

MainWindow::~MainWindow()
{
    {
        // 初始化文件
        //路径为程序路径下，文件不存在会自行创建
        QString iniFilePath = QCoreApplication::applicationDirPath() + "/config.ini";
        //新建QSettings类，路径+格式
        QSettings settings(iniFilePath,QSettings::IniFormat);
        //设置编码，使支持中文
        settings.setIniCodec("UTF-8");
        settings.setValue("ADDRESS/baudRate",ui->baudRate->currentIndex());
        settings.setValue("ADDRESS/dataBit",ui->dataBit->currentIndex());
        settings.setValue("ADDRESS/stopBit",ui->stopBit->currentIndex());
        settings.setValue("ADDRESS/checkBit",ui->checkBit->currentIndex());
        settings.setValue("ADDRESS/endString",ui->endString->currentIndex());
    }
    delete ui;
}

void MainWindow::clearData()           // 清空缓存
{
    QPushButton *clearButton = qobject_cast<QPushButton*>(sender());
    if(clearButton==ui->clearRecvCache)
        ui->recvData->clear();
    else if(clearButton==ui->clearSentCache)
        ui->sentData->clear();
}

void MainWindow::saveCache()           // 保存缓存
{
    QString data_cache;
    QPushButton *saveButton = qobject_cast<QPushButton*>(sender());
    if(saveButton==ui->saveRecvCache)
        data_cache=ui->recvData->toPlainText();
    else if(saveButton==ui->saveSentCache)
        data_cache=ui->sentData->toPlainText();

    QString fileName = QFileDialog::getSaveFileName(this,
                                                    tr("Save cache"),
                                                    "",
                                                    tr("Text file(*.txt)"));
    QFile file(fileName);

    if (!file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
        QMessageBox::critical(this, "critical", tr("File save failed!"),
                              QMessageBox::Yes, QMessageBox::Yes);
    }
    else
    {
        QTextStream stream(&file);
        stream << data_cache;
        stream.flush();
        file.close();
    }
}

void MainWindow::serialPortButton() // 选择端口
{
    ui->serialPort->clear();
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->serialPort->addItem(info.portName());
    }
}

void MainWindow::serialToggleButton()// 启动、关闭串口
{
    static bool openSerial = false;
    if(!openSerial)
    {
        //设置串口名
        serial.setPortName(ui->serialPort->currentText());
        //设置波特率
        switch(ui->baudRate->currentIndex())
        {
        case 0: serial.setBaudRate(QSerialPort::Baud4800);break;
        case 1: serial.setBaudRate(QSerialPort::Baud9600);break;
        case 2: serial.setBaudRate(QSerialPort::Baud19200);break;
        case 3: serial.setBaudRate(QSerialPort::Baud38400);break;
        case 4: serial.setBaudRate(QSerialPort::Baud57600);break;
        case 5: serial.setBaudRate(QSerialPort::Baud115200);break;
        default:serial.setBaudRate(QSerialPort::Baud9600);break;
        }
        //设置数据位数
        switch(ui->checkBit->currentIndex())
        {
        case 0: serial.setDataBits(QSerialPort::Data8); break;
        case 1: serial.setDataBits(QSerialPort::Data7); break;
        case 2: serial.setDataBits(QSerialPort::Data6); break;
        case 3: serial.setDataBits(QSerialPort::Data5); break;
        default:serial.setDataBits(QSerialPort::Data8); break;
        }
        //设置奇偶校验
        switch(ui->dataBit->currentIndex())
        {
        case 0: serial.setParity(QSerialPort::NoParity); break;
        case 1: serial.setParity(QSerialPort::OddParity); break;
        case 2: serial.setParity(QSerialPort::EvenParity); break;
        case 3: serial.setParity(QSerialPort::SpaceParity); break;
        default:serial.setParity(QSerialPort::NoParity); break;
        }
        //设置停止位
        switch(ui->stopBit->currentIndex())
        {
        case 0: serial.setStopBits(QSerialPort::OneStop); break;
        case 1: serial.setStopBits(QSerialPort::TwoStop); break;
        default:serial.setStopBits(QSerialPort::OneStop); break;
        }

        serial.setFlowControl(QSerialPort::NoFlowControl);  //设置流控制

        if(!serial.open(QIODevice::ReadWrite))  //打开串口
        {
            ui->recvData->append(zh("串口打开失败\n"));
            return;
        }

        ui->Sent->setEnabled(true); //发送按键使能
        ui->serialToggle->setText(zh("Close Serial"));
        openSerial = true;

        ui->recvData->append(zh("串口打开成功\n"));
        return;
    }
    else
    {
        openSerial = false;

        serial.close(); //关闭串口
        ui->serialPort->setEnabled(true);   //下拉菜单控件使能
        ui->serialToggle->setText("Open Serial");
        ui->Sent->setEnabled(false);    //发送按键失能

        ui->recvData->append(zh("串口已关闭\n"));
        return;
    }
}

void MainWindow::serialSentButton()     // 发送数据
{
    QByteArray data = ui->sentData->toPlainText().toUtf8();
    switch (ui->endString->currentIndex()) {
    case 1:data+='\r';break;
    case 2:data+='\n';break;
    case 3:data+="\r\n";break;
    }
    serial.write(data);
}

void MainWindow::serialPort_readyRead()
{
    QByteArray buffer = serial.readAll();   //从接收缓冲区中读取数据
    QString recv = ui->recvData->toPlainText(); //从界面中读取以前收到的数据

    recv += QString(buffer);
    ui->recvData->setPlainText(recv); //重新显示
    ui->recvData->moveCursor(QTextCursor::End);
}
